//
//  ContactManager.m
//  PersonalOCTest
//
//  Created by zlf on 2025/4/28.
//

#import "ContactManager.h"
#import <CommonCrypto/CommonCrypto.h>
#import <Contacts/Contacts.h>
#import <zlib.h>

@implementation ContactManager

#pragma mark - 请求通讯录权限并处理
- (void)requestContactPermissionAndProcess {
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    
    // 请求通讯录权限
    [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@"通讯录权限已授权");
//            [self processContacts];
            [self exportContactsToVCF];
        } else {
            NSLog(@"通讯录权限被拒绝");
        }
    }];
}

- (void)exportContactsToVCF {
    // 定义需要获取的联系人字段（根据需求扩展）
//    NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactJobTitleKey, CNContactOrganizationNameKey, CNContactPostalAddressesKey];
    // 1. 定义请求字段（包含所有必要属性）
    NSArray *keys = @[[CNContactVCardSerialization descriptorForRequiredKeys]];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
    NSMutableString *vcfContent = [[NSMutableString alloc] init];
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    // 遍历联系人
    NSError *fetchError;
    [contactStore enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        NSError *vCardError;
        // 将 CNContact 转换为 vCard 格式字符串
        NSData *vCardData = [CNContactVCardSerialization dataWithContacts:@[contact] error:&vCardError];
        if (vCardError) {
            NSLog(@"读取vcard失败: %@", vCardError.localizedDescription);
        }
        if (vCardData) {
            NSString *vCardString = [[NSString alloc] initWithData:vCardData encoding:NSUTF8StringEncoding];
            NSLog(@"vcardString print 打印出来是: %@", vCardString);
            [vcfContent appendString:vCardString];
        }
    }];
    if (fetchError) {
        NSLog(@"读取通讯录失败: %@", fetchError.localizedDescription);
        return;
    }
    // 保存到文件
    if (vcfContent.length > 0) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsPath = [paths firstObject];
        NSString *filePath = [documentsPath stringByAppendingPathComponent:@"pcontacts.vcf"];
        if ([vcfContent writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil]) {
            NSLog(@"vCard文件已保存至：%@", filePath);
        }
        
    }
}

#pragma mark - 处理通讯录数据
- (void)processContacts {
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    NSError *error = nil;
    
    // 定义需要获取的字段
    NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
    
    NSMutableArray *contactsArray = [NSMutableArray array];
    
    // 遍历通讯录
    [contactStore enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        NSString *fullName = [NSString stringWithFormat:@"%@ %@", contact.familyName, contact.givenName];
        NSMutableArray *phoneNumbers = [NSMutableArray array];
        
        for (CNLabeledValue *labelValue in contact.phoneNumbers) {
            CNPhoneNumber *phoneNumber = labelValue.value;
            [phoneNumbers addObject:phoneNumber.stringValue];
        }
        
        NSDictionary *contactDict = @{
            @"name": fullName,
            @"phoneNumbers": phoneNumbers
        };
        [contactsArray addObject:contactDict];
    }];
    
    if (error) {
        NSLog(@"读取通讯录失败: %@", error.localizedDescription);
        return;
    }
    NSLog(@"通讯录显示===>: %@", contactsArray);
    // 将通讯录数据转换为 JSON
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:contactsArray options:0 error:&error];
    if (error) {
        NSLog(@"JSON 序列化失败: %@", error.localizedDescription);
        return;
    }
    
    // 压缩并加密数据
    NSData *compressedEncryptedData = [self compressAndEncryptData:jsonData];
    
    // 存储到本地
    NSString *filePath = [self saveDataToLocal:compressedEncryptedData];
    
    // 上传到服务器
    [self uploadToServerWithFilePath:filePath];
}

#pragma mark - 压缩并加密数据
- (NSData *)compressAndEncryptData:(NSData *)data {
    // 压缩数据
    NSData *compressedData = [self compressData:data];
    
    // 加密数据 (AES 加密)
    NSData *encryptedData = [self encryptData:compressedData withKey:@"your-encryption-key"];
    
    return encryptedData;
}

- (NSData *)compressData:(NSData *)data {
    if (!data) return nil;
    
    NSMutableData *compressedData = [NSMutableData dataWithLength:compressBound(data.length)];
    uLongf compressedSize = compressedData.length;
    
    if (compress(compressedData.mutableBytes, &compressedSize, data.bytes, data.length) == Z_OK) {
        compressedData.length = compressedSize;
        return compressedData;
    }
    
    return nil;
}

- (NSData *)encryptData:(NSData *)data withKey:(NSString *)key {
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    size_t bufferSize = data.length + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t encryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128,
                                          NULL,
                                          data.bytes, data.length,
                                          buffer, bufferSize,
                                          &encryptedSize);
    
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    }
    
    free(buffer);
    return nil;
}

#pragma mark - 存储到本地
- (NSString *)saveDataToLocal:(NSData *)data {
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"contacts.dat"];
    [data writeToFile:filePath atomically:YES];
    NSLog(@"数据已存储到本地: %@", filePath);
    return filePath;
}

#pragma mark - 模拟上传到服务器
- (void)uploadToServerWithFilePath:(NSString *)filePath {
    // 模拟上传到服务器
    NSLog(@"开始上传文件到服务器: %@", filePath);
    
    // 假设上传成功
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"文件上传成功: %@", filePath);
    });
}

#pragma mark - 测试联系人管理

/// 批量添加测试联系人
- (void)addTestContactsWithCount:(NSInteger)count completion:(void(^)(NSInteger successCount, NSError * _Nullable error))completion {
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    
    // 检查权限
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status != CNAuthorizationStatusAuthorized) {
        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSError *permissionError = [NSError errorWithDomain:@"ContactManagerDomain" 
                                                                   code:1001 
                                                               userInfo:@{NSLocalizedDescriptionKey: @"通讯录权限被拒绝"}];
                    completion(0, permissionError);
                });
                return;
            }
            [self performAddTestContactsWithCount:count contactStore:contactStore completion:completion];
        }];
        return;
    }
    
    [self performAddTestContactsWithCount:count contactStore:contactStore completion:completion];
}

- (void)performAddTestContactsWithCount:(NSInteger)count contactStore:(CNContactStore *)contactStore completion:(void(^)(NSInteger successCount, NSError * _Nullable error))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSMutableArray *contactsToAdd = [NSMutableArray array];
        
        // 预定义的测试数据
        NSArray *firstNames = @[@"Alice", @"Bob", @"Charlie", @"Diana", @"Edward", @"Fiona", @"George", @"Helen", @"Ivan", @"Julia"];
        NSArray *lastNames = @[@"Smith", @"Johnson", @"Williams", @"Brown", @"Jones", @"Garcia", @"Miller", @"Davis", @"Rodriguez", @"Martinez"];
        NSArray *companies = @[@"Apple Inc", @"Google", @"Microsoft", @"Amazon", @"Tesla", @"Facebook", @"Netflix", @"Adobe", @"Oracle", @"IBM"];
        NSArray *jobTitles = @[@"Engineer", @"Manager", @"Designer", @"Analyst", @"Developer", @"Consultant", @"Director", @"Specialist", @"Coordinator", @"Assistant"];
        
        // 生成测试联系人
        for (NSInteger i = 0; i < count; i++) {
            CNMutableContact *contact = [[CNMutableContact alloc] init];
            
            // 设置姓名（以Test开头便于识别和删除）
            NSString *firstName = firstNames[i % firstNames.count];
            NSString *lastName = lastNames[i % lastNames.count];
            contact.givenName = [NSString stringWithFormat:@"Test%@", firstName];
            contact.familyName = lastName;
            
            // 设置电话号码
            CNPhoneNumber *phoneNumber = [CNPhoneNumber phoneNumberWithStringValue:[NSString stringWithFormat:@"138%04ld%04ld", (long)(1000 + i), (long)(arc4random() % 10000)]];
            CNLabeledValue *phoneValue = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMain value:phoneNumber];
            contact.phoneNumbers = @[phoneValue];
            
            // 设置邮箱
            NSString *email = [NSString stringWithFormat:@"test%@.%@@example.com", firstName.lowercaseString, lastName.lowercaseString];
            CNLabeledValue *emailValue = [CNLabeledValue labeledValueWithLabel:CNLabelWork value:email];
            contact.emailAddresses = @[emailValue];
            
            // 设置公司信息
            contact.organizationName = companies[i % companies.count];
            contact.jobTitle = jobTitles[i % jobTitles.count];
            
            // 设置地址
            CNMutablePostalAddress *address = [[CNMutablePostalAddress alloc] init];
            address.street = [NSString stringWithFormat:@"%ld Test Street", (long)(100 + i)];
            address.city = @"Test City";
            address.state = @"Test State";
            address.postalCode = [NSString stringWithFormat:@"%05ld", (long)(10000 + i)];
            address.country = @"Test Country";
            CNLabeledValue *addressValue = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:address];
            contact.postalAddresses = @[addressValue];
            
            [contactsToAdd addObject:contact];
        }
        
        // 批量保存联系人
        CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
        for (CNMutableContact *contact in contactsToAdd) {
            [saveRequest addContact:contact toContainerWithIdentifier:nil];
        }
        
        NSError *saveError = nil;
        BOOL success = [contactStore executeSaveRequest:saveRequest error:&saveError];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (success) {
                NSLog(@"成功添加 %ld 个测试联系人", (long)count);
                completion(count, nil);
            } else {
                NSLog(@"添加测试联系人失败: %@", saveError.localizedDescription);
                completion(0, saveError);
            }
        });
    });
}

/// 删除所有测试联系人（姓名以"Test"开头的联系人）
- (void)deleteAllTestContactsWithCompletion:(void(^)(NSInteger deletedCount, NSError * _Nullable error))completion {
    [self deleteContactsWithNamePrefix:@"Test" completion:completion];
}

/// 删除指定姓名前缀的联系人
- (void)deleteContactsWithNamePrefix:(NSString *)namePrefix completion:(void(^)(NSInteger deletedCount, NSError * _Nullable error))completion {
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    
    // 检查权限
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status != CNAuthorizationStatusAuthorized) {
        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSError *permissionError = [NSError errorWithDomain:@"ContactManagerDomain" 
                                                                   code:1001 
                                                               userInfo:@{NSLocalizedDescriptionKey: @"通讯录权限被拒绝"}];
                    completion(0, permissionError);
                });
                return;
            }
            [self performDeleteContactsWithNamePrefix:namePrefix contactStore:contactStore completion:completion];
        }];
        return;
    }
    
    [self performDeleteContactsWithNamePrefix:namePrefix contactStore:contactStore completion:completion];
}

- (void)performDeleteContactsWithNamePrefix:(NSString *)namePrefix contactStore:(CNContactStore *)contactStore completion:(void(^)(NSInteger deletedCount, NSError * _Nullable error))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 查找要删除的联系人
        NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactIdentifierKey];
        CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
        
        NSMutableArray *contactsToDelete = [NSMutableArray array];
        NSError *fetchError = nil;
        
        [contactStore enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
            if ([contact.givenName hasPrefix:namePrefix] || [contact.familyName hasPrefix:namePrefix]) {
                [contactsToDelete addObject:contact];
            }
        }];
        
        if (fetchError) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(0, fetchError);
            });
            return;
        }
        
        if (contactsToDelete.count == 0) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"没有找到以'%@'开头的联系人", namePrefix);
                completion(0, nil);
            });
            return;
        }
        
        // 批量删除联系人
        CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
        for (CNContact *contact in contactsToDelete) {
            CNMutableContact *mutableContact = [contact mutableCopy];
            [saveRequest deleteContact:mutableContact];
        }
        
        NSError *deleteError = nil;
        BOOL success = [contactStore executeSaveRequest:saveRequest error:&deleteError];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (success) {
                NSLog(@"成功删除 %ld 个以'%@'开头的联系人", (long)contactsToDelete.count, namePrefix);
                completion(contactsToDelete.count, nil);
            } else {
                NSLog(@"删除联系人失败: %@", deleteError.localizedDescription);
                completion(0, deleteError);
            }
        });
    });
}

/// 获取所有测试联系人（姓名以"Test"开头的联系人）
- (void)getAllTestContactsWithCompletion:(void(^)(NSArray<NSDictionary *> *testContacts, NSError * _Nullable error))completion {
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    
    // 检查权限
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status != CNAuthorizationStatusAuthorized) {
        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSError *permissionError = [NSError errorWithDomain:@"ContactManagerDomain" 
                                                                   code:1001 
                                                               userInfo:@{NSLocalizedDescriptionKey: @"通讯录权限被拒绝"}];
                    completion(@[], permissionError);
                });
                return;
            }
            [self performGetAllTestContactsWithContactStore:contactStore completion:completion];
        }];
        return;
    }
    
    [self performGetAllTestContactsWithContactStore:contactStore completion:completion];
}

- (void)performGetAllTestContactsWithContactStore:(CNContactStore *)contactStore completion:(void(^)(NSArray<NSDictionary *> *testContacts, NSError * _Nullable error))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, 
                          CNContactEmailAddressesKey, CNContactOrganizationNameKey, CNContactJobTitleKey];
        CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
        
        NSMutableArray *testContacts = [NSMutableArray array];
        NSError *fetchError = nil;
        
        [contactStore enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
            if ([contact.givenName hasPrefix:@"Test"]) {
                NSMutableArray *phoneNumbers = [NSMutableArray array];
                for (CNLabeledValue *labelValue in contact.phoneNumbers) {
                    CNPhoneNumber *phoneNumber = labelValue.value;
                    [phoneNumbers addObject:phoneNumber.stringValue];
                }
                
                NSMutableArray *emails = [NSMutableArray array];
                for (CNLabeledValue *labelValue in contact.emailAddresses) {
                    [emails addObject:labelValue.value];
                }
                
                NSDictionary *contactDict = @{
                    @"firstName": contact.givenName ?: @"",
                    @"lastName": contact.familyName ?: @"",
                    @"fullName": [NSString stringWithFormat:@"%@ %@", contact.givenName ?: @"", contact.familyName ?: @""],
                    @"phoneNumbers": phoneNumbers,
                    @"emails": emails,
                    @"company": contact.organizationName ?: @"",
                    @"jobTitle": contact.jobTitle ?: @""
                };
                [testContacts addObject:contactDict];
            }
        }];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (fetchError) {
                NSLog(@"获取测试联系人失败: %@", fetchError.localizedDescription);
                completion(@[], fetchError);
            } else {
                NSLog(@"找到 %ld 个测试联系人", (long)testContacts.count);
                completion([testContacts copy], nil);
            }
        });
    });
}

@end